﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows.Media;
using System.Text.RegularExpressions;
using System.Windows;


namespace vmlModel
{

    public class vmlUtils
    {
        #region "xmlns"
        public static XNamespace pkg = "http://schemas.microsoft.com/office/2006/xmlPackage";
        public static XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
        public static XNamespace v = "urn:schemas-microsoft-com:vml";
        #endregion

        #region "Lengths"
        public static double InchPerPoint = 72;
        public static double InchPerPica = 6;
        public static double InchPerCentimeter = 2.54;

        public static double PixelPerPoint = 96 / InchPerPoint;
        public static double PixelPerTwip = PixelPerPoint / 20;

        public static double PixelPerInch = PixelPerPoint / InchPerPoint;
        public static double PixelPerPica = PixelPerInch * InchPerPica;
        public static double PixelPerCentimeter = PixelPerInch * InchPerCentimeter;
        public static double PixelPerMillimeter = PixelPerCentimeter * 10;

        #endregion

        public static double GetLength(string lengthatrrValue)
        {
            if (lengthatrrValue == null)
                return double.NaN;
            lengthatrrValue = lengthatrrValue.Trim();
            if (lengthatrrValue == "")
                return double.NaN;

            if (lengthatrrValue == "inherit")
                return double.NaN;
            double ReallengthatrrValue = double.NaN;
            foreach (string unit_identifier in new string[] { "in", "cm", "mm", "pt", "pc", "px", "%" })
            {
                if (lengthatrrValue.EndsWith(unit_identifier))
                {
                    ReallengthatrrValue = Double.Parse(lengthatrrValue.Substring(0, lengthatrrValue.Length - unit_identifier.Length).Trim());
                    switch (unit_identifier)
                    {
                        case "in":
                            ReallengthatrrValue *= vmlUtils.PixelPerInch;
                            break;
                        case "cm":
                            ReallengthatrrValue *= vmlUtils.PixelPerCentimeter;
                            break;
                        case "mm":
                            ReallengthatrrValue *= vmlUtils.PixelPerMillimeter;
                            break;
                        case "pt":
                            ReallengthatrrValue *= vmlUtils.PixelPerPoint;
                            break;
                        case "pc":
                            ReallengthatrrValue *= vmlUtils.PixelPerPica;
                            break;
                        case "px":
                            break;
                        case "%":
                            break;
                        default:
                            break;
                    }
                    break;
                }
            }

            return ReallengthatrrValue;

        }
        /// <summary>
        /// Convert a string string to a .NET Color object.
        /// </summary>
        /// <param name="strColor">string name or a hex string: "FFFFFF", "#000000"</param>
        public static Color StringToColor(string strColor)
        {
            Color color = Colors.Transparent;
            if (!strColor.Contains("#"))
            {
                System.Drawing.Color ncolor = System.Drawing.Color.FromName(strColor);

                try
                {
                    byte nri
                       = byte.Parse(ncolor.R.ToString());
                    byte ngi
                       = byte.Parse(ncolor.G.ToString());
                    byte nbi
                       = byte.Parse(ncolor.B.ToString());
                    color = Color.FromRgb(nri, ngi, nbi);
                }
                catch
                {
                    // you can choose whether to throw an exception
                    //throw new ArgumentException("Conversion failed.");
                    return Colors.Transparent;
                }
                return color;
            }

            string hc = ExtractHexDigits(strColor);
            hc = ("ffffff" + hc).Substring(hc.Length, 6);
            string r = hc.Substring(0, 2);
            string g = hc.Substring(2, 2);
            string b = hc.Substring(4, 2);
            try
            {
                byte ri
                   = byte.Parse(r, System.Globalization.NumberStyles.HexNumber);
                byte gi
                   = byte.Parse(g, System.Globalization.NumberStyles.HexNumber);
                byte bi
                   = byte.Parse(b, System.Globalization.NumberStyles.HexNumber);
                color = Color.FromRgb(ri, gi, bi);
            }
            catch
            {
                // you can choose whether to throw an exception
                //throw new ArgumentException("Conversion failed.");
                return Colors.Transparent;
            }
            return color;
        }
        /// <summary>
        /// Extract only the hex digits from a string.
        /// </summary>
        public static string ExtractHexDigits(string input)
        {
            // remove any characters that are not digits (like #)
            Regex isHexDigit
               = new Regex("[abcdefABCDEF\\d]+", RegexOptions.Compiled);
            string newnum = "";
            foreach (char c in input)
            {
                if (isHexDigit.IsMatch(c.ToString()))
                    newnum += c.ToString();
            }
            return newnum;

        }



        public static DoubleCollection DashStyleFromVML(string dashstyleAtrrValue)
        {
            /// if the value comes from the VML as string array
            /// go to http://msdn.microsoft.com/en-us/library/bb264085(VS.85).aspx for more informations
            dashstyleAtrrValue = dashstyleAtrrValue.ToLower();
            if (dashstyleAtrrValue.Contains(" "))
            {
                string[] values = dashstyleAtrrValue.Split(' ');
                DoubleCollection Dashes = new DoubleCollection();
                values.ToList().ForEach(s => Dashes.Add(double.Parse(s)));
                return Dashes;
            }
            // predifined dashes
            switch (dashstyleAtrrValue)
            {
                case "solid": //(default) 
                    return DashStyles.Solid.Dashes;
                case "shortdash":
                    return new DoubleCollection() { 1, 1 };
                case "shortdot":
                    return new DoubleCollection() { 0, 2 };
                case "shortdashdot":
                    return new DoubleCollection() { 2, 2, 0, 2 };
                case "Shortdashdotdot":
                    return DashStyles.DashDotDot.Dashes;
                case "dot":
                    return DashStyles.Dot.Dashes;
                case "dash":
                    return DashStyles.Dash.Dashes;
                case "longdash":
                    return new DoubleCollection() { 8, 2 };
                case "dashdot":
                    //return DashStyles.DashDot.Dashes;
                    return new DoubleCollection() { 1, 1, 0, 1 };
                case "longdashdot":
                    return new DoubleCollection() { 8, 2, 1, 2 };
                case "longdashdotdot":
                    return new DoubleCollection() { 8, 2, 1, 2 };
                default:
                    break;
            }

            return DashStyles.Solid.Dashes;

        }

        public static int GetPostiveAngle(int A)
        {
            if (A < 0) return 360 + A;

            return A;
        }

        internal static int GetPercent(int value)
        {
            throw new NotImplementedException();
        }

        public static double GetPercent(string value)
        {
            //the atrrValue string as a percentage or a fixed precision number (f suffix)
            if (value.Contains('f'))
            {
                value = value.Replace("f", "");
                return double.Parse(value) / 65536;
            }
            if (value.Contains("%"))
            {
                value = value.Replace("%", "");
            }
            return double.Parse(value);
        }

        public static double GetHypotenuseLength(string atrrValue)
        {
            Point pt = GetPoint(atrrValue);

            return Math.Sqrt(Math.Pow(pt.X, 2) + Math.Pow(pt.Y, 2));
        }

        public static Point GetPoint(string atrrValue)
        {
            var xy = atrrValue.Split(',');

            Point point = new Point();

            point.X = GetLength(xy[0]);
            if (xy.Length == 1)
            {
                point.Y = point.X;
            }
            else
            {
                point.Y = GetLength(xy[1]);
            }
            return point;
        }
    }
}

     
